import requests, json, os, shutil
from lxml.etree import HTML
import platform

# 所有版本驱动的路径 https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json

def upzip_file(zip_path=None, unzip_path=None):
    """
    :zip_path 压缩文件路径
    :unzip_path 解压文件路径
    :return 解压 zip 文件,返回所有解压文件夹下的路径
    """
    import zipfile
    zip_file = zipfile.ZipFile(zip_path)
    if not os.path.isdir(unzip_path):
        os.mkdir(unzip_path)
    for names in zip_file.namelist():
        zip_file.extract(names, unzip_path)
    zip_file.close()
    return [os.path.join(unzip_path, i).replace('\\', '/') for i in zip_file.namelist()]


def down_chromedriver_zip(urll=None, path=None, version=None):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    res1 = requests.get(urll, headers=headers)
    response1 = json.loads(res1.text)
    for i in response1:
        if 'chromedriver_win32' in i['name']:
            zip_url = i['url']
            name = zip_url.split('/')[-1]
            zip_path = os.path.join(path, name)
            res2 = requests.get(zip_url, headers=headers)
            with open(zip_path, 'wb') as f:
                f.write(res2.content)
            uzip_path = zip_path.replace('.zip', '')
            paths = upzip_file(zip_path, uzip_path)
            for chromedriver_path in paths:
                if not chromedriver_path.endswith('.exe'):
                    if os.path.exists(chromedriver_path):
                        os.remove(chromedriver_path)
                    continue
                os.rename(chromedriver_path, chromedriver_path.replace('.exe', '') + f'_{version}.exe')
            if os.path.exists(zip_path):
                os.remove(zip_path)

def get_down_url(chrome_version, headers, platform_name="win64"):
    """ 获取chromedriver 驱动压缩文件链接
    platform_name = ["linux64","mac-arm64","mac-x64","win32","win64"]
    """
    import sys
    if not platform_name:
        platform_name = sys.platform
    bit_number = platform.architecture()[0]
    url = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json'
    proxies = {"http": None, "https": None}
    res = requests.get(url, headers=headers, proxies=proxies)
    response = json.loads(res.text)
    down_url = None
    versions = []
    for ver in response['versions']:
        version = ver['version']
        if str(chrome_version) not in version:
            continue
        if not str(version).startswith(str(chrome_version)):
            continue
        versions.append(version)

    if len(versions) > 0:
        # versiondict = [[int(i.replace('.', '')), i] for i in versions]
        # version_new = sorted(versiondict, key=lambda x: x[0])[-1][1]
        # print('version_new:', version_new)
        version = versions[-1]
        if 'linux' in str(platform_name) and bit_number == '64bit':
            down_url = f'https://storage.googleapis.com/chrome-for-testing-public/{version}/linux64/chromedriver-linux64.zip'
        elif 'win' in str(platform_name) and bit_number == '32bit':
            down_url = f'https://storage.googleapis.com/chrome-for-testing-public/{version}/win32/chromedriver-win32.zip'
        elif 'win' in str(platform_name) and bit_number == '64bit':
            down_url = f'https://storage.googleapis.com/chrome-for-testing-public/{version}/win64/chromedriver-win64.zip'
        else:
            down_url = f'https://storage.googleapis.com/chrome-for-testing-public/{version}/mac-x64/chromedriver-mac-x64.zip'
        return down_url
        # chrome_paths = ver['downloads']['chrome']
        # for i in chrome_paths:
        #     if i["platform"] == platform:
        #         down_url = i['url']
        #         return down_url
    return down_url

def get_down_url0(version, headers):
    # 只返回了最新版本
    url = 'https://googlechromelabs.github.io/chrome-for-testing/#stable'
    zip_url = None
    try:
        res = requests.get(url, headers=headers)
        response = HTML(res.text)
        trs = response.xpath('//section/div[@class="table-wrapper"]/table//tr')
        for tr in trs:
            zip_url = tr.xpath('./td/code[contains(text(), "zip")]/text()')
            if 'chromedriver-win32' not in ''.join(zip_url):
                continue
            code = tr.xpath('./td/code[not(contains(text(), "zip"))]/text()')
            if '200' not in ''.join(code):
                continue
            Binary = tr.xpath('./th[1]/code/text()')
            if 'chromedriver' not in Binary:
                continue
            zip_url = zip_url[0]
            if str(version) in zip_url:
                break
        if isinstance(zip_url, list):
            zip_url = zip_url[0]
    except Exception as e:
        print('e1:', e)
        zip_url = None
    return zip_url

def down_chromedriver_version1(path, version=None):
    uzip_path = ".\\chromedriver"
    chromedriver_filename = os.path.join(uzip_path, f'chromedriver_{version}.exe')
    if os.path.exists(chromedriver_filename) and os.path.isfile(chromedriver_filename):
        print("文件已存在！")
        return chromedriver_filename

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    # zip_url = get_down_url0(version, headers)
    zip_url = get_down_url(version, headers)
    if not zip_url:
        print('获取驱动链接失败')
        return None
    print('zip_url:', zip_url)
    try:
        name = zip_url.split('/')[-1]
        zip_path = os.path.join(path, name)

        flag = False
        for i in range(5):
            try:
                res2 = requests.get(zip_url, headers=headers)
                print('res2_status_code::', res2.status_code)
                flag = True
                break
            except:
                pass
        if not flag:
            return None

        with open(zip_path, 'wb') as f:
            f.write(res2.content)
        # uzip_path = zip_path.replace('.zip', '').replace('chromedriver-win32', 'chromedriver_win32')
        # uzip_path = './chromedriver_win32'
        print("zip_path", zip_path)
        print("uzip_path",uzip_path)
        paths = upzip_file(zip_path, uzip_path)
        for chromedriver_path in paths:
            print("chromedriver_path",chromedriver_path)
            if not chromedriver_path.endswith('.exe'):
                if os.path.exists(chromedriver_path):
                    os.remove(chromedriver_path)
                continue
            # os.rename(chromedriver_path, chromedriver_path.replace('.exe', '') + f'_{version}.exe')
            shutil.copy(chromedriver_path, chromedriver_filename)
            os.remove(chromedriver_path)
        exe_path = os.path.join(uzip_path, 'chromedriver-win32')
        if os.path.exists(exe_path):
            os.rmdir(exe_path)
        if os.path.exists(zip_path):
            os.remove(zip_path)

        return chromedriver_filename
    except Exception as e:
        print('e2:', e)
        return None

def down_chromedriver_version(path, version0=None):
    uzip_path = ".\\chromedriver"
    chromedriver_filename = os.path.join(uzip_path, f'chromedriver_{version0}.exe')
    if os.path.exists(chromedriver_filename) and os.path.isfile(chromedriver_filename):
        print("文件已存在！")
        return chromedriver_filename

    url2 = 'https://registry.npmmirror.com/-/binary/chromedriver/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    if version0 and int(version0) > 116:
        return down_chromedriver_version1(path, version0)
    try:
        res = requests.get(url2, headers=headers)
        response = json.loads(res.text)
    except:
        response = {}
    versions = []
    dic = {}
    for i in response:
        if not i['name'].split('.')[0].isdigit():
            continue
        version = int(i['name'].split('.')[0])
        if i['name'].startswith(f'{version0}.'):
            versions.append({version: i['url']})
        if len(dic) == 0:
            dic[version] = i['url']
        if len(dic) > 0 and version > list(dic.keys())[0]:
            dic.pop(list(dic.keys())[0])
            dic[version] = i['url']
    if len(versions) == 0 and len(dic) > 0:
        versions.append(dic)
    if len(versions) > 0:
        for k, zip_url in versions[-1].items():
            try:
                down_chromedriver_zip(zip_url, path, k)
                return chromedriver_filename
            except:
                pass
    return  None

if __name__ == '__main__':
    filepath = down_chromedriver_version1('.\\', 129)
    print(filepath)